#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include  <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>


#include "bloom_filter.h"
#include "util.h"

#define TYPECAST_LBF_PORT 2004
#define MAX_BUFFER_SIZE 1024


int main(int argc, char **argv) 
{ 
    if (argc % 2 == 0)
    {
        printf("Usage: test_LBF_update [mgrpAddr LBF] [mgrpAddr LBF] ... \n");
        return -1;
    }

    int sockfd;
    u_int32_t local_ip_addr = get_local_ip_address(); 

    struct sockaddr_in dst_addr; 
    memset(&dst_addr, 0, sizeof(struct sockaddr_in));
    dst_addr.sin_family = AF_INET; 
    dst_addr.sin_port = htons(TYPECAST_LBF_PORT); 
    dst_addr.sin_addr.s_addr = htonl(local_ip_addr); 
    /*
    struct hostent * he = gethostbyname("localhost");
    memcpy((char*)&dst_addr.sin_addr, he->h_addr, he->h_length);
    */
    sockfd = socket(PF_INET, SOCK_DGRAM, 0);

    char buf[MAX_BUFFER_SIZE];
    memset(buf, 0, MAX_BUFFER_SIZE);

    char * tail = buf;

    int multicast_group_count;
    multicast_group_count = (argc - 1) / 2;

    *tail = multicast_group_count;
    tail += sizeof(u_int8_t);

    printf("Multicast group count: %d.\n", multicast_group_count);

    int i;
    u_int32_t *grp_addr; 
    for (i = 0; i < multicast_group_count; i++)
    {
        grp_addr = tail; 
        *grp_addr = (u_int32_t) inet_addr(argv[i*2 + 1]);
        printf("Group addr=%s\n", ip_to_string(ntohl(*grp_addr))); 
        tail += sizeof(u_int32_t);
        bloom_filter_t LBF;
        hex_string_to_bloom_filter(argv[i*2 + 2], LBF);
        copy_bloom_filter(tail, LBF);
        tail += sizeof(bloom_filter_t);

        printf("Multicast group %d: addr = %s , LBF = %s.\n", i, argv[i*2+1], argv[i*2 + 2]);
    }
    

    int msglen = sendto(sockfd, buf, tail - buf, 0, (struct sockaddr *) &dst_addr, sizeof(dst_addr) );
    if (msglen < 0)
    {
        perror("Error sendto\n");
    }

    printf("updateLBF success.\n");

    return 0;
}

